/**
 * @author: mattwang@tencent.com
 * @date: 2012-9-25
 */

#ifndef __MPI_DEF_H__
#define __MPI_DEF_H__

#include <mpi.h>
#include <stdarg.h>

const int kBufferSize = 1024;
static int g_mpi_size = 1;
static int g_mpi_rank = 0;

inline bool is_local_feature(int feature_id) {
	return (feature_id % g_mpi_size) == g_mpi_rank;
}

inline int get_local_feature_id(int feature_id) {
	return feature_id / g_mpi_size;
}

inline int get_global_feature_id(int feature_id) {
	return feature_id * g_mpi_size + g_mpi_rank;
}

inline int get_local_feature_num(int global_feature_num) {
	return global_feature_num / g_mpi_size + (global_feature_num % g_mpi_size > g_mpi_rank ? 1 : 0);
}

inline void RootPrint(const char format[], ...) {
	if (g_mpi_rank == 0) {
		va_list argp;
		char buffer[kBufferSize];
		va_start(argp, format);
		vsnprintf(buffer, sizeof(buffer), format, argp);
		printf("%s", buffer);
		va_end(argp);
	}
	MPI_Barrier (MPI_COMM_WORLD);
}

#define CHKERRQ(info) if(info != MPI_SUCCESS) { \
		RootPrint("Error: %s in %s:%d. Return value is %d", \
                              __FUNCTION__, __FILE__, __LINE__, info); \
    MPI_Abort(MPI_COMM_WORLD, -1); }

inline void LocalPrint(const char format[], ...) {
	va_list argp;
	char buffer[kBufferSize];
	va_start(argp, format);
	vsnprintf(buffer, sizeof(buffer), format, argp);
	va_end(argp);

	for (int i = 0; i < g_mpi_size; ++i) {
		if (i == g_mpi_rank) {
			printf("######## Rank %d ########\n", g_mpi_rank);
			printf("%s", buffer);
		}

		MPI_Barrier (MPI_COMM_WORLD);
	}
}

#endif
